package com.example.server.plugins.routing

import com.example.commons.Ret
import com.example.commons.models.ApkInfo
import com.example.commons.models.AppVersion
import com.example.server.db.dao.AppVersionDao
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.resources.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.request.*
import io.ktor.server.resources.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.utils.io.core.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.File
import kotlin.text.String


private val logger: Logger = LoggerFactory.getLogger("AppVersion")

fun Route.configAppVersionRouting() {

    get<LatestAppVersion> {
        val p = AppVersionDao.getInstance().findLatest(it.applicationId, it.code, it.variantName)
        if (p == null) {
            call.respond(Ret.fail<AppVersion>(msg = "没有数据"))
        } else {
            call.respond(Ret.success<AppVersion>(p))
        }
    }

    authenticate("auth-basic") {
        post("/appVersions/upload") {
            val multipartData = call.receiveMultipart()
            var apkInfo: ApkInfo? = null
            var apkPart: PartData.FileItem? = null
            try {
                multipartData.forEachPart { part ->
                    when (part) {
                        is PartData.FormItem -> {
                            if (part.contentType == ContentType.Application.Json) {
                                // 当json处理
                                if (part.name == "apk-metadata") {
                                    apkInfo = Json.decodeFromString(ApkInfo.serializer(), part.value)
                                    logger.info("apkInfo = ${apkInfo}")
                                }
                            } else {
                                logger.info("${part.name} = ${part.value}")
                            }
                        }
                        is PartData.FileItem -> {
//                            part.provider().readBytes()
                            if (part.name == "apk") {
                                apkPart = part
                            } else if (part.name == "apk-metadata") {
                                val fileBytes = part.streamProvider().readBytes()
                                apkInfo = Json.decodeFromString(ApkInfo.serializer(), String(fileBytes))
                                logger.info("apkInfo = ${apkInfo}")
                            }
                        }
                        is PartData.BinaryItem -> {
                            val bytes = part.provider().readBytes()

                        }
                        else -> {
                            logger.info("${part.name} = ${part.contentType}")
                        }
                    }
                }
                if (apkInfo != null && apkPart != null) {
                    val fileName = apkPart!!.originalFileName as String
                    val fileBytes = apkPart!!.streamProvider().readBytes()
                    File("uploads/apks/$fileName").writeBytes(fileBytes)
                    AppVersionDao.getInstance().insert(apkInfo!!.appVersion)

                    call.respond("upload ok, ${call.request.uri}")
                } else {
                    call.respond(HttpStatusCode.BadRequest, "文件不可为空，描述信息也不可为空")
                }
            } catch (e: java.lang.Exception) {
                call.respond(HttpStatusCode.InternalServerError, e)
            }
        }
    }
}

@Serializable
@Resource("/appVersion/latest")
data class LatestAppVersion(
    val applicationId: String,
    val code: Int,
    val variantName: String? = "",
)